﻿namespace com.stifel.BranchMgmtDao
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;

    using com.stifel.Extensions.GuidExtensions;

    using Microsoft.SharePoint;

    using CustomObject = StifelPhoto;

    public class StifelPhotoDao : StifelBaseDao
    {
        #region Fields

        public const string ListName = "stifelphotos";

        #endregion Fields

        #region Constructors

        public StifelPhotoDao( )
            : base(ListName)
        {
            CurrentWebUrl = ConfiguredWebUrl;
        }

        public StifelPhotoDao( string currentWebUrl )
            : base(ListName)
        {
            this.CurrentWebUrl = currentWebUrl;
        }

        #endregion Constructors

        #region Methods

        public CustomObject Add( CustomObject value )
        {
            using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
            {
                using ( SPWeb spWeb = spSite.OpenWeb( ) )
                {
                    SPListItem sourceItem = value.ListItem;
                    SPFile sourceFile = sourceItem.File;
                    byte[ ] buffer = sourceFile.OpenBinary( );

                    SPList spList = spWeb.Lists[ ListTitle ];

                    SPContentTypeId contentTypeId = spWeb.AvailableContentTypes[ value.ListItem.ContentType.Name ].Id;
                    spWeb.Users.GetByID( value.Author.Id );
                    Hashtable properties = new Hashtable( );
                    properties.Add( StifelPhoto.Fields.Value.ContentTypeId, contentTypeId.ToString( ) );
                    properties.Add( StifelPhoto.Fields.Value.PrimaryAuthor, value.PrimaryAuthor );
                    properties.Add( StifelPhoto.Fields.Value.DatePictureTaken, value.DatePictureTaken );
                    if ( value.BranchLookupId.HasValue )
                        properties.Add( StifelPhoto.Fields.Value.BranchLookupId, new SPFieldLookupValue( value.BranchLookupId.Value, value.BranchLookupTitle ).ToString( ) );
                    if ( value.PhotoTypeId.HasValue )
                        properties.Add( StifelPhoto.Fields.Value.PhotoTypeId, new SPFieldLookupValue( value.PhotoTypeId.Value, value.PhotoTypeTitle ).ToString( ) );
                    properties.Add( StifelPhoto.Fields.Value.Copyright, value.Copyright );
                    properties.Add( StifelPhoto.Fields.Value.Keywords, value.Keywords );
                    properties.Add( StifelPhoto.Fields.Value.Comments, value.Comments );
                    string valueName = value.Name;
                    foreach ( SPFile f in spList.RootFolder.Files )
                    {
                        if ( f.Name.Equals( valueName, StringComparison.OrdinalIgnoreCase ) )
                        {
                            Guid g = Guid.NewGuid( );
                            valueName = string.Format( "{0}{1}", g.ToShortGuid( ), valueName );
                            break;
                        }
                    }
                    SPFile spFile = spList.RootFolder.Files.Add( valueName, buffer, properties, spWeb.Users.GetByID( value.Author.Id ), spWeb.Users.GetByID( value.Editor.Id ), value.Created.Value, value.Modified.Value, false );

                    spFile.Update( );
                    return GetByUniqueId( spFile.Item.UniqueId );
                }
            }
        }

        public void Clear( )
        {
            using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
            {
                using ( SPWeb spWeb = spSite.OpenWeb( ) )
                {
                    SPList spList = spWeb.Lists[ ListTitle ];
                    SPQuery spQuery = new SPQuery
                    {
                        Query = QueryDefn.Get( QueryDefn.All )
                    };
                    List<SPListItem> items = spList.GetItems( spQuery ).Cast<SPListItem>( ).ToList( );
                    for ( int i = items.Count - 1; i >= 0; i-- )
                        items[ i ].Delete( );
                }
            }
        }

        public void Delete( List<Guid> values )
        {
            using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
            {
                using ( SPWeb spWeb = spSite.OpenWeb( ) )
                {
                    SPList spList = spWeb.Lists[ ListTitle ];
                    foreach ( Guid uniqueId in values )
                    {
                        SPQuery spQuery = new SPQuery
                        {
                            Query = QueryDefn.Get( QueryDefn.ByUniqueId, uniqueId )
                        };
                        SPListItemCollection spListItemCollection = spList.GetItems( spQuery );

                        if ( spListItemCollection.Count > 0 )
                            spListItemCollection[ 0 ].Delete( );
                    }
                }
            }
        }

        public List<CustomObject> GetByBranchLocation( int id )
        {
            using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
            {
                using ( SPWeb spWeb = spSite.OpenWeb( ) )
                {
                    SPList spList = spWeb.Lists[ ListTitle ];
                    SPQuery spQuery = new SPQuery
                    {
                        Query = QueryDefn.Get( QueryDefn.ByBranchLocation, id )
                    };
                    SPListItemCollection spListItemCollection = spList.GetItems( spQuery );

                    Guid parentListId = spList.ID;

                    List<CustomObject> list = new List<CustomObject>( );
                    foreach ( SPListItem spListItem in spListItemCollection )
                    {
                        CustomObject o = CustomObject.Get( spListItem );
                        list.Add( o );
                    }
                    return list;
                }
            }
        }

        public CustomObject GetById( int id )
        {
            using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
            {
                using ( SPWeb spWeb = spSite.OpenWeb( ) )
                {
                    SPList spList = spWeb.Lists[ ListTitle ];
                    SPQuery spQuery = new SPQuery
                    {
                        Query = QueryDefn.Get( QueryDefn.ById, id )
                    };
                    SPListItemCollection spListItemCollection = spList.GetItems( spQuery );

                    Guid parentListId = spList.ID;

                    if ( spListItemCollection.Count > 0 )
                    {
                        CustomObject o = CustomObject.Get( spListItemCollection[ 0 ] );
                        return o;
                    }
                    else
                        return null;
                }
            }
        }

        public CustomObject GetByTitle( string value )
        {
            using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
            {
                using ( SPWeb spWeb = spSite.OpenWeb( ) )
                {
                    SPList spList = spWeb.Lists[ ListTitle ];
                    SPQuery spQuery = new SPQuery
                    {
                        Query = QueryDefn.Get( QueryDefn.ByTitle, value )
                    };
                    SPListItemCollection spListItemCollection = spList.GetItems( spQuery );

                    Guid parentListId = spList.ID;

                    if ( spListItemCollection.Count > 0 )
                    {
                        CustomObject o = CustomObject.Get( spListItemCollection[ 0 ] );
                        return o;
                    }
                    else
                        return null;
                }
            }
        }

        public CustomObject GetByUniqueId( Guid uniqueId )
        {
            using ( SPSite spSite = new SPSite( CurrentWebUrl ) )
            {
                using ( SPWeb spWeb = spSite.OpenWeb( ) )
                {
                    SPList spList = spWeb.Lists[ ListTitle ];
                    SPQuery spQuery = new SPQuery
                    {
                        Query = QueryDefn.Get( QueryDefn.ByUniqueId, uniqueId )
                    };
                    SPListItemCollection spListItemCollection = spList.GetItems( spQuery );

                    if ( spListItemCollection.Count > 0 )
                    {
                        CustomObject o = CustomObject.Get( spListItemCollection[ 0 ] );
                        return o;
                    }
                    else
                        return null;
                }
            }
        }

        #endregion Methods

        #region Nested Types

        class QueryDefn
        {
            #region Fields

            public const string All = "<OrderBy><FieldRef Name='Title' Ascending='True'/></OrderBy>";
            public const string ByBranchLocation = "<Where><Eq><FieldRef Name='sn_bi_BranchLoc' LookupId='TRUE' /><Value Type='Lookup'>{0}</Value></Eq></Where>";
            public const string ById = "<Where><Eq><FieldRef Name='ID' /><Value Type='Counter'>{0}</Value></Eq></Where>";
            public const string ByTitle = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>{0}</Value></Eq></Where>";
            public const string ByUniqueId = "<Where><Eq><FieldRef Name='UniqueId' /><Value Type='Guid'>{0}</Value></Eq></Where>";

            #endregion Fields

            #region Methods

            public static string Get( string query, params object[ ] args )
            {
                return string.Format( query, args );
            }

            #endregion Methods
        }

        #endregion Nested Types
    }
}